package main

import (
	"bytes"
	"crypto/rand"
	"encoding/base64"
	"fmt"
	"log"

	"github.com/tjfoc/gmsm/sm2"
	"github.com/tjfoc/gmsm/sm3"
	"github.com/tjfoc/gmsm/sm4"
	"github.com/tjfoc/gmsm/x509"
)

func main() {
	//fmt.Println("SM2 Test start ")

	// testSM2()
	// testSM3()
	// testSM4()

	//testSM()
	testDecrypt()
}


func testX509(){
	x509.WritePrivateKeyToPem()
	x509.MarshalSm2EcryptedPrivateKey()
}

func testDecrypt() {
	fmt.Println("\n====SM Test start ")
	priString := "BggqgRzPVQGCLQ=="
	//pubString := "AFTPi32JIWG1vFeuLjSEE9X2v4MYXc6ClHwDcJlsDM5q"
	cipher := []byte("3074022100e756b8c47cb7e0575438559127fe98ae8b91266deae2df84b3a5ef04054e71a702201ec4b37c254d5e9a43f26316202dc0ec4b3b792aa9e78dbf9eb07203f949d29f04201041cb488452db9955bc8b89e687789c200ce894a2c7a34a6fffa7d38a8a6b70040bc9754a008dc8096090bcf")

	// //从base64数据中加载公钥
	// pubKeyData, _ := base64.StdEncoding.DecodeString(pubString)

	// //从base64数据中加载私钥
	priKeyData, err := base64.StdEncoding.DecodeString(priString)

	fmt.Println("private key from string", priKeyData, len(priKeyData), err)

	priKey, err := sm2.GenerateKey(bytes.NewReader(priKeyData))
	if err != nil {
		fmt.Println("Gen privKey error", err)
	}

	//
	message, _ := priKey.DecryptAsn1(cipher)

	fmt.Printf("原文:%x\n", string(message))

	fmt.Println("\n====SM Test end ")
}

func testSM() {
	fmt.Println("\n====SM Test start ")

	priv, err := sm2.GenerateKey(rand.Reader) // 生成密钥对
	if err != nil {
		log.Fatal(err)
	}

	//私钥 D => base64
	pByte := priv.D.Bytes()
	priString := base64.StdEncoding.EncodeToString(pByte)
	fmt.Println("private key:", priString)

	//公钥
	pubKey := &priv.PublicKey
	pubString := base64.StdEncoding.EncodeToString(sm2.Compress(pubKey))
	fmt.Println("public key:", pubString)

	//原文
	message := []byte("who are you")
	ciphertxt, err := pubKey.EncryptAsn1(message, rand.Reader) //sm2加密
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("加密结果:%x\n", ciphertxt)

	fmt.Println("\n====SM Test end ")
}

func testSM2() {
	fmt.Println("\n====SM2 Test start ")
	priv, err := sm2.GenerateKey(rand.Reader) // 生成密钥对
	if err != nil {
		log.Fatal(err)
	}

	//fmt.Println("SM2 test key", priv.Curve, priv.PublicKey)
	//priv.Curve.Params().BitSize/8
	fmt.Println("SM2 test private key", priv)

	msg := []byte("Tongji Fintech Research Institute")
	pub := &priv.PublicKey

	fmt.Println("SM2 test public key", pub)

	ciphertxt, err := pub.EncryptAsn1(msg, rand.Reader) //sm2加密
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("加密结果:%x\n", ciphertxt)
	plaintxt, err := priv.DecryptAsn1(ciphertxt) //sm2解密
	if err != nil {
		log.Fatal(err)
	}
	if !bytes.Equal(msg, plaintxt) {
		log.Fatal("原文不匹配")
	}

	pkey := sm2.Compress(pub)
	pub2 := sm2.Decompress(pkey)

	fmt.Printf("sm2 test public key compress: %x\n", pkey)

	//t2 := "aabbccddddeee"
	p2, _ := pub2.EncryptAsn1(msg, rand.Reader) //sm2加密
	r2, _ := priv.DecryptAsn1(p2)
	fmt.Println("解密结果:", string(r2))

	sign, err := priv.Sign(rand.Reader, msg, nil) //sm2签名
	if err != nil {
		log.Fatal(err)
	}
	isok := pub.Verify(msg, sign) //sm2验签
	fmt.Printf("Verified: %v\n", isok)
	fmt.Println("====SM2 Test end ")
}

func testSM3() {
	fmt.Println("\n====SM3 Test start ")
	data := "test"
	h := sm3.New()
	h.Write([]byte(data))
	sum := h.Sum(nil)
	fmt.Printf("digest value is: %x\n", sum)
	fmt.Println("====SM3 Test end ")
}

func testSM4() {
	fmt.Println("\n====SM4 Test start ")
	key := []byte("1234567890abcdef")
	fmt.Printf("key = %v\n", key)
	data := []byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10}
	fmt.Printf("key = %v\n", key)
	fmt.Printf("data = %x\n", data)
	iv := []byte("0000000000000000")

	sm4.SetIV(iv)
	//sm4.Sm4GCM()
	//设置SM4算法实现的IV值,不设置则使用默认值
	ecbMsg, err := sm4.Sm4Ecb(key, data, true) //sm4Ecb模式pksc7填充加密
	if err != nil {
		fmt.Println("sm4 enc error: ", err)
		return
	}
	fmt.Printf("ecbMsg = %x\n", ecbMsg)
	ecbDec, err := sm4.Sm4Ecb(key, ecbMsg, false) //sm4Ecb模式pksc7填充解密
	if err != nil {
		fmt.Println("sm4 dec error: ", err)
		return
	}
	fmt.Printf("ecbDec = %x\n", ecbDec)
	fmt.Println("====SM4 Test End ")
}
